import {setIndicator} from "./models/indicator";
import {getAuthInfos, getCurrentProxySetting, onCurrentProxySettingChanged} from "./models/proxy";
import {base} from "./models/base.ts";


export const initBookmarks = async () => {
    const response = await fetch(base + "/api-admin/application/list")
    if (!response.ok) {
        throw new Error('Network response was not ok')
    }
    const allData = await response.json()
    let res = await chrome.bookmarks.search({title: 'termius'})

    let maxParentId = "2"
    if (res.length) {
        await chrome.bookmarks.removeTree(res[0].id)
    }

    let termius = await chrome.bookmarks.create(
        {'parentId': '1', 'title': 'termius'}
    );

    maxParentId = termius.id

    let getOrCreateBookmarks = async (name: string, parentId: string, url: string | undefined) => {
        return await chrome.bookmarks.create(
            {'parentId': parentId, 'title': name, 'url': url}
        )
    }

    let currentLevel = allData
    let next = []
    while (currentLevel && currentLevel.length) {
        for (const item of currentLevel) {
            if (item.children && item.children.length) {
                let res = await getOrCreateBookmarks(
                    item.name, item.parentId ? item.parentId : maxParentId, undefined
                );

                for (const child of item.children) {
                    child.parentId = res.id
                    next.push(child)
                }
            } else {
                await getOrCreateBookmarks(
                    item.name, item.parentId ? item.parentId : maxParentId, item.content
                );

                if (item.identity) {
                    item.identity = JSON.parse(item.identity)
                }

                if (item.identity && item.identity.length) {
                    chrome.userScripts.register([{
                        id: item.content,
                        matches: [item.content + '/*'],
                        world: 'MAIN',
                        js: [{
                            code: `    let toast = document.createElement("link")
    toast.href = "https://cdn.staticfile.net/toastify-js/1.12.0/toastify.min.css"
    toast.rel = "stylesheet"
    document.head.appendChild(toast)

!function(t,o){"object"==typeof module&&module.exports?module.exports=o():t.Toastify=o()}(this,function(t){function i(t){return new i.lib.init(t)}function n(t,o){return o.offset[t]?isNaN(o.offset[t])?o.offset[t]:o.offset[t]+"px":"0px"}function l(t,o){return!(!t||"string"!=typeof o)&&!!(t.className&&-1<t.className.trim().split(/\\s+/gi).indexOf(o))}return i.defaults={oldestFirst:!0,text:"Toastify is awesome!",node:void 0,duration:3e3,selector:void 0,callback:function(){},destination:void 0,newWindow:!1,close:!1,gravity:"toastify-top",positionLeft:!1,position:"",backgroundColor:"",avatar:"",className:"",stopOnFocus:!0,onClick:function(){},offset:{x:0,y:0},escapeMarkup:!0,ariaLive:"polite",style:{background:""}},i.lib=i.prototype={toastify:"1.12.0",constructor:i,init:function(t){return t=t||{},this.options={},this.toastElement=null,this.options.text=t.text||i.defaults.text,this.options.node=t.node||i.defaults.node,this.options.duration=0===t.duration?0:t.duration||i.defaults.duration,this.options.selector=t.selector||i.defaults.selector,this.options.callback=t.callback||i.defaults.callback,this.options.destination=t.destination||i.defaults.destination,this.options.newWindow=t.newWindow||i.defaults.newWindow,this.options.close=t.close||i.defaults.close,this.options.gravity="bottom"===t.gravity?"toastify-bottom":i.defaults.gravity,this.options.positionLeft=t.positionLeft||i.defaults.positionLeft,this.options.position=t.position||i.defaults.position,this.options.backgroundColor=t.backgroundColor||i.defaults.backgroundColor,this.options.avatar=t.avatar||i.defaults.avatar,this.options.className=t.className||i.defaults.className,this.options.stopOnFocus=(void 0===t.stopOnFocus?i.defaults:t).stopOnFocus,this.options.onClick=t.onClick||i.defaults.onClick,this.options.offset=t.offset||i.defaults.offset,this.options.escapeMarkup=(void 0!==t.escapeMarkup?t:i.defaults).escapeMarkup,this.options.ariaLive=t.ariaLive||i.defaults.ariaLive,this.options.style=t.style||i.defaults.style,t.backgroundColor&&(this.options.style.background=t.backgroundColor),this},buildToast:function(){if(!this.options)throw"Toastify is not initialized";var t,o,i,s,e=document.createElement("div");for(t in e.className="toastify on "+this.options.className,this.options.position?e.className+=" toastify-"+this.options.position:!0===this.options.positionLeft?(e.className+=" toastify-left",console.warn("Property \`positionLeft\` will be depreciated in further versions. Please use \`position\` instead.")):e.className+=" toastify-right",e.className+=" "+this.options.gravity,this.options.backgroundColor&&console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.'),this.options.style)e.style[t]=this.options.style[t];return this.options.ariaLive&&e.setAttribute("aria-live",this.options.ariaLive),this.options.node&&this.options.node.nodeType===Node.ELEMENT_NODE?e.appendChild(this.options.node):(this.options.escapeMarkup?e.innerText=this.options.text:e.innerHTML=this.options.text,""!==this.options.avatar&&((s=document.createElement("img")).src=this.options.avatar,s.className="toastify-avatar","left"==this.options.position||!0===this.options.positionLeft?e.appendChild(s):e.insertAdjacentElement("afterbegin",s))),!0===this.options.close&&((s=document.createElement("button")).type="button",s.setAttribute("aria-label","Close"),s.className="toast-close",s.innerHTML="&#10006;",s.addEventListener("click",function(t){t.stopPropagation(),this.removeElement(this.toastElement),window.clearTimeout(this.toastElement.timeOutValue)}.bind(this)),i=0<window.innerWidth?window.innerWidth:screen.width,("left"==this.options.position||!0===this.options.positionLeft)&&360<i?e.insertAdjacentElement("afterbegin",s):e.appendChild(s)),this.options.stopOnFocus&&0<this.options.duration&&(o=this,e.addEventListener("mouseover",function(t){window.clearTimeout(e.timeOutValue)}),e.addEventListener("mouseleave",function(){e.timeOutValue=window.setTimeout(function(){o.removeElement(e)},o.options.duration)})),void 0!==this.options.destination&&e.addEventListener("click",function(t){t.stopPropagation(),!0===this.options.newWindow?window.open(this.options.destination,"_blank"):window.location=this.options.destination}.bind(this)),"function"==typeof this.options.onClick&&void 0===this.options.destination&&e.addEventListener("click",function(t){t.stopPropagation(),this.options.onClick()}.bind(this)),"object"==typeof this.options.offset&&(i=n("x",this.options),s=n("y",this.options),i="left"==this.options.position?i:"-"+i,s="toastify-top"==this.options.gravity?s:"-"+s,e.style.transform="translate("+i+","+s+")"),e},showToast:function(){var t;if(this.toastElement=this.buildToast(),!(t="string"==typeof this.options.selector?document.getElementById(this.options.selector):this.options.selector instanceof HTMLElement||"undefined"!=typeof ShadowRoot&&this.options.selector instanceof ShadowRoot?this.options.selector:document.body))throw"Root element is not defined";var o=i.defaults.oldestFirst?t.firstChild:t.lastChild;return t.insertBefore(this.toastElement,o),i.reposition(),0<this.options.duration&&(this.toastElement.timeOutValue=window.setTimeout(function(){this.removeElement(this.toastElement)}.bind(this),this.options.duration)),this},hideToast:function(){this.toastElement.timeOutValue&&clearTimeout(this.toastElement.timeOutValue),this.removeElement(this.toastElement)},removeElement:function(t){t.className=t.className.replace(" on",""),window.setTimeout(function(){this.options.node&&this.options.node.parentNode&&this.options.node.parentNode.removeChild(this.options.node),t.parentNode&&t.parentNode.removeChild(t),this.options.callback.call(t),i.reposition()}.bind(this),400)}},i.reposition=function(){for(var t={top:15,bottom:15},o={top:15,bottom:15},i={top:15,bottom:15},s=document.getElementsByClassName("toastify"),e=0;e<s.length;e++){var n=!0===l(s[e],"toastify-top")?"toastify-top":"toastify-bottom",a=s[e].offsetHeight;n=n.substr(9,n.length-1);(0<window.innerWidth?window.innerWidth:screen.width)<=360?(s[e].style[n]=i[n]+"px",i[n]+=a+15):!0===l(s[e],"toastify-left")?(s[e].style[n]=t[n]+"px",t[n]+=a+15):(s[e].style[n]=o[n]+"px",o[n]+=a+15)}return this},i.lib.init.prototype=i.lib,i});

    let root = document.createElement("div")
    root.style.position = "fixed"
    root.style.top = "50%"
    root.style.right = "4px"
    root.style.transform = "translateY(-50%)"
    root.style.display = "flex"
    root.style.flexDirection = "row"
    root.style.justifyContent = "center"
    root.style.alignItems = "center"

    let button = document.createElement("div")
    button.style.transition = "transform 0.3s cubic-bezier(0.25,0.1,0.25,1)"
    button.style.marginRight = "8px"
    button.style.mixBlendMode = "difference"
    button.style.cursor = "pointer"
    button.style.color = "red"
    button.innerHTML = \`<svg focusable="false" data-icon="left" width="1em" height="1em" fill="currentColor" aria-hidden="true"
              viewBox="64 64 896 896">
             <path
                 d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"></path>
         </svg>\`
    root.appendChild(button)

    let isOpened = false
    button.addEventListener("click", function () {
        if (isOpened) {
            panel.style.maxWidth = "0px"
            button.style.transform = "rotate(0deg)"
        } else {
            panel.style.maxWidth = "300px"
            button.style.transform = "rotate(180deg)"
        }
        isOpened = !isOpened
    })

    //面板
    let panel = document.createElement("div")
    panel.style.maxWidth = "0px"
    panel.style.height = "500px"
    panel.style.overflow = "hidden"
    panel.style.transition = "max-width 0.5s cubic-bezier(0.25,0.1,0.25,1)"
    panel.style.backgroundColor = "#fff"
    panel.style.boxSizing = "border-box"
    panel.style.borderRadius = "4px"
    panel.style.boxShadow = "0 2px 8px rgba(0,0,0,0.3)"

    let item = {
        "identity": [
            {
                "username": "admin",
                "password": "123456",
                "tag": "管理员111"
            },
            {
                "username": "user1",
                "password": "654321",
                "tag": "普通用户"
            }
        ],
        "serverList":[
            {

            },
            {

            }
        ]
    }

    //复制密码
    const copyPassword = (password) => {
        const input = document.createElement("input")
        input.value = password
        document.body.appendChild(input)
        input.select()
        document.execCommand("copy")
        document.body.removeChild(input)
        Toastify({
            text: "密码已复制到粘贴板",
            className: "info",
            style: {
                background: "linear-gradient(to right, #00b09b, #96c93d)",
            }
        }).showToast();
    }
    
    panel.innerHTML = \`
        <div style="padding: 16px">
            <h3>账号密码</h3>
            <div>
            ${item && item.identity && item.identity.map((u: any) => `<p>身份：${u.tag}，用户名：${u.username}，密码：<a href=" javascript:void(0)" onclick="copyPassword('${u.password}')">复制</a></p>`).join("")}
            </div>
            <h3>服务器</h3>
            ${item && item.serverList && item.serverList.map((u: any) => `<p>标识：${u.tag}，访问：<a target="_blank" href="${base}/server?connectId=${u.server.id}">连接</a></p>`).join("")}
        </div>
            \`

    root.appendChild(panel)

    document.body.appendChild(root)
`
                        }]
                    }]);
                }
            }
        }

        currentLevel = next
        next = []
    }

    let r = await chrome.userScripts.getScripts()
    console.log(r)
}


// indicator
async function initIndicator() {
    await setIndicator(await getCurrentProxySetting())
    onCurrentProxySettingChanged(async (proxy) => {
        await setIndicator(proxy)
    })


    try {
        initBookmarks()
    } catch (e) {
        console.error(e)
    }

}

initIndicator().catch(console.error)


// proxy auth provider
class ProxyAuthProvider {
    // requests[requestID] = request attempts. 0 means the 1st attempt
    static requests: Record<string, number> = {}

    static onCompleted(details: chrome.webRequest.WebResponseDetails) {
        if (ProxyAuthProvider.requests[details.requestId]) {
            delete ProxyAuthProvider.requests[details.requestId]
        }
    }

    static onAuthRequired(details: chrome.webRequest.WebAuthenticationChallengeDetails,
                          callback?: (response: chrome.webRequest.BlockingResponse) => void) {

        if (!details.isProxy) {
            callback && callback({cancel: true})
            return
        }

        if (ProxyAuthProvider.requests[details.requestId] === undefined) {
            // 0 means the 1st attempt
            ProxyAuthProvider.requests[details.requestId] = 0
        } else {
            ProxyAuthProvider.requests[details.requestId]++
        }

        getAuthInfos(details.challenger.host, details.challenger.port).then((authInfos) => {
            const auth = authInfos.at(ProxyAuthProvider.requests[details.requestId])
            if (!auth) {
                callback && callback({cancel: true})
                return
            }

            callback && callback({
                authCredentials: {
                    username: auth.username,
                    password: auth.password,
                }
            })
        })
    }
}

chrome.webRequest.onAuthRequired.addListener(ProxyAuthProvider.onAuthRequired, {urls: ["<all_urls>"]}, ['asyncBlocking'])
chrome.webRequest.onCompleted.addListener(ProxyAuthProvider.onCompleted, {urls: ["<all_urls>"]})
chrome.webRequest.onErrorOccurred.addListener(ProxyAuthProvider.onCompleted, {urls: ["<all_urls>"]})
chrome.proxy.onProxyError.addListener(console.warn)

// chrome.bookmarks.getTree(e => {
//     console.log(e)
// })

